#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#include "PAP_defs.h"
#include "APP_SMAC_API.h"
#include "freescale_radio_hardware.h"
#include "CommunicationsHandler.h"

#define CHANNEL_NUMBER 4

UINT8 gu8Channel = CHANNEL_NUMBER;     
UINT16 gu16Events = 0;

uint8 gu8RTxMode; /* needed for s-mac, application can read this variable */
				  /* rtx_mode is the software state variable of the radio */

uint8 u8Comm_LastPacketNum = 0;
uint8 u8Comm_LastSCIPacketSent = 0;
uint8 u8Comm_SMACTxPending = 0;

uint8 u8Comm_SCIPending = 0;

uint8 u8Comm_RxSMACPacket[COMM_SMAC_RX_PACKET_SIZE];
uint8 u8Comm_TxSMACPacket[COMM_SMAC_TX_PACKET_SIZE];

uint8 u8Comm_RxSCIPacket[COMM_SCI_RX_PACKET_SIZE] = { "12345678901" };
uint8 u8Comm_TxSCIPacket[COMM_SCI_TX_PACKET_SIZE];

uint8 u8Comm_SCIRequest = 0;

uint8 u8Comm_LastSCITxStatus = SCI_STATUS_SUCCESS;
uint8 u8Comm_LastSCIRxStatus = SCI_STATUS_SUCCESS;

uint8 u8contador_pendejadas_rx = 0;
uint8 u8contador_pendejadas_tx = 0;

uint8 u8signal_quality = 0;

void main(void) 
{
    static tRxPacket rx_packet;  //SMAC structure for RX packets
	static tTxPacket tx_packet;	 //SMAC structure for TX packets
	
    //Initialize the packet.
    tx_packet.u8DataLength = COMM_SMAC_TX_PACKET_SIZE;  //Set TX default to 10
    
    //Load the address of our txbuffer into tx structure.
    tx_packet.pu8Data = &u8Comm_TxSMACPacket[0];
    	    
    rx_packet.u8DataLength = COMM_SMAC_RX_PACKET_SIZE;  //Set RX default to 15
    
    //Load the address of our rxbuffer into rx structure
    rx_packet.pu8Data = &u8Comm_RxSMACPacket[0];
    	            
    rx_packet.u8MaxDataLength = 100;	//Define the max buffer size.
    rx_packet.u8Status = 0;				//initialize the status packet to 0.

    MCUInit();		//Initialize the mcu, setup GPIOs, SPI, clock scheme, etc.
    RadioInit();
    (void)MLMESetMC13192ClockRate(0);  /* Set initial Clk speed from MC13192s CLKO*/
	UseExternalClock();	/* switch clock sources to EXTERNAL clock */
	
	/* include your start up code here */	
    EnableInterrupts; /* Turn on system interrupts */
	(void)MLMESetChannelRequest(CHANNEL_NUMBER);	
    (void)MLMEMC13192PAOutputAdjust(MAX_POWER);	//Set Max power setting
    
    // Iwal y esta madre hay que quitarla, pero es para asegurarnos que el
    // timer para el timout del radio este a 250khz
    //(void)MLMESetMC13192TmrPrescale (3);

    vfnComm_BuildSMACPacket ();

    vfnSCI_SetBaudRate (SCI_62500BAUD);
    vfnSCI_Init ();

	vfnComm_TimeoutWatchdogSetup();

    (void)MLMERXEnableRequest(&rx_packet, 0);

    for(;;) 
    {
        if (u8Comm_SMACTxPending)
        {
            vfnSCI1_DisableInterrupts();
        
            u8signal_quality = MLMELinkQuality();
        
            // Return radio to idle mode
            (void)MLMERXDisableRequest();
        
            vfnComm_BuildSMACPacket ();
        
            // Wait for channel to be free
            while (MLMEEnergyDetect() < 150);
            
            // Once channel is free, send SMAC packet
            (void)MCPSDataRequest(&tx_packet);
 
            // Clear SCI flags before returning to the main thread
            (void)u8SCI1_RxPending();
            (void)u8SCI1_ReadByte();
            
            u8Comm_SMACTxPending = 0;
            
            // Once packet is sent
            // Set radio to rx mode with no timeout
            (void)MLMERXEnableRequest(&rx_packet, 0);
            
            vfnSCI1_EnableInterrupts();
        }
        
        // If Xbee has to receive SCI
        if (u8Comm_SCIPending == COMM_SCI_RX_REQUEST)
        {
            if(!u8Comm_HandleSCIRx())
            {
            	u8Comm_LastSCIRxStatus = SCI_STATUS_FAILURE;
            }
            u8Comm_SCIPending = 0;
            vfnSCI1_EnableInterrupts(); 
        }
        
        // If Xbee has to transmit SCI
        if (u8Comm_SCIPending == COMM_SCI_TX_REQUEST)
        {
        	if(u8Comm_LastSCIPacketSent != u8Comm_LastPacketNum)
        	{
	            if(!u8Comm_HandleSCITx())
	            {
	            	u8Comm_LastSCITxStatus = SCI_STATUS_FAILURE;
	            }
        	}
            u8Comm_SCIPending = 0;
            vfnSCI1_EnableInterrupts(); 
        }
        
        //(void)MLMERXEnableRequest(&rx_packet, 0);
        
        //__RESET_WATCHDOG(); /* feeds the dog */
    } /* loop forever */
  /* please make sure that you never leave main */
}

uint8 MCPSDataIndication(tRxPacket *gsRxPacket)
{
    if (gsRxPacket->u8Status == SUCCESS)
    {
        // If the MAC address contained in the packet matches that of the airplane
        // then react to the packet
        if ((gsRxPacket->pu8Data[0] == COMM_MAC_ADDR_HIGH) && 
            (gsRxPacket->pu8Data[1] == COMM_MAC_ADDR_LOW))
        {

            u8Comm_SMACTxPending = 1;
            
            u8Comm_LastPacketNum = gsRxPacket->pu8Data[2];                    
          
        }
        
        // Clear SCI flags before returning to the main thread
        (void)u8SCI1_RxPending();
        (void)u8SCI1_ReadByte();
        
        return SUCCESS;
    }
    if (gsRxPacket->u8Status == TIMEOUT)
    {
        // Clear SCI flags before returning to the main thread
        (void)u8SCI1_RxPending();
        (void)u8SCI1_ReadByte();
        
        return TIMEOUT;
    }
    
}

void MLMEMC13192ResetIndication() 
{
	//Notifies you that the MC13192 has been reset.
	//Application must handle this here.

    return;
}

